package org.greyhawk.samonitor.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.greyhawk.samonitor.vo.HtmlSource;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.beans.StringBean;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.ImageTag;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service
@Scope(value="prototype")
public class SiteCrawler {


	public boolean isValidUrl(String urlPath) {
		String regex = "http://([\\w-]+\\.)+[\\w-]+(/[\\w-\\./?%=]*)?";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(urlPath);
		return matcher.find();
	}


	public String createName(String url) {
		String fileName = "";
		Random random = new Random();
		long file = Math.abs(random.nextLong());
		if (url.endsWith("gif")) {
			fileName = file + ".gif";
		}
		if (url.endsWith("jpg")) {
			fileName = file + ".jpg";
		}
		if (url.endsWith("swf"))
			fileName = file + ".swf";
		return fileName;
	}


	

	public byte[] crawResources(String urlPath) throws Exception {
		System.out.println("urlPath:"+urlPath);
		byte[] bytes = null;
		HttpClient httpClient = new HttpClient();
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				15000);
		GetMethod getMethod = new GetMethod(urlPath);
		getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 60000);
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
		int statusCode = httpClient.executeMethod(getMethod);
		if (statusCode != HttpStatus.SC_OK)
			return null;
		bytes = getMethod.getResponseBody();
		getMethod.releaseConnection();
		return bytes;
	}
	
	public HtmlSource crawSource(String urlPath) throws Exception {
		System.out.println("urlPath:"+urlPath);
		byte[] bytes = null;
		HttpClient httpClient = new HttpClient();
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				15000);
		GetMethod getMethod = new GetMethod(urlPath);
		getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 60000);
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
		int statusCode = httpClient.executeMethod(getMethod);
		if (statusCode != HttpStatus.SC_OK)
			return null;
		bytes = getMethod.getResponseBody();
		String charset = getMethod.getResponseCharSet();
		getMethod.releaseConnection();
		return new HtmlSource(charset,bytes);
	}

	public List<String> parseImageUrl(String urlPath) throws Exception {
		List<String> imageUrlList = new ArrayList<String>();
		Parser parser = new Parser(urlPath);
		NodeFilter filter = new NodeClassFilter(ImageTag.class);
		NodeList nodeList = parser.extractAllNodesThatMatch(filter);
		for (int i = 0; i < nodeList.size(); i++) {
			ImageTag tag = (ImageTag) nodeList.elementAt(i);
			String imageUrl = tag.getImageURL();
			imageUrlList.add(imageUrl);
		}
		return imageUrlList;

	}
	
	public List<String> parseText(HtmlSource source)throws Exception{
		
		List<String> texts = new ArrayList<String>();
		System.out.println("html source charSet:"+source.getCharset());
		Parser parser = null;
		if(source.getCharset().equals("ISO-8859-1"))
			parser = Parser.createParser(new String(source.getContent(),"GBK"), "GBK");
		else
		    parser = Parser.createParser(new String(source.getContent(),source.getCharset()), source.getCharset());
		NodeFilter filter = new NodeClassFilter(LinkTag.class);
		NodeList nodeList = parser.extractAllNodesThatMatch(filter);
		for(int i = 0;i<nodeList.size();i++){
			LinkTag tag = (LinkTag)nodeList.elementAt(i);
			String text = tag.getLinkText();
			System.out.println("text:"+text);
			texts.add(text);
		}
		return texts;
	}
	

	public List<String> parseFlashUrl(String html) throws Exception {
		List<String> urlList = new ArrayList<String>();
		String regex = "http://([\\w-]+\\.)+[\\w-]+(/[\\w-\\./?%=]*)?\\.swf";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(html);
		while (matcher.find()) {
			urlList.add(matcher.group());
		}
		return urlList;
	}

	public List<String> parseFlash(byte[] htmlData) throws Exception {
		String html = new String(htmlData);
		List<String> urlList = this.parseFlashUrl(html);
		return urlList;
	}

	public List<String> parseImage(byte[] htmlDate) throws Exception {
		String html = new String(htmlDate);
		List<String> urlList = new ArrayList<String>();
		String regex = "http://([\\w-]+\\.)+[\\w-]+(/[\\w-\\./?%=]*)?\\.jpg";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(html);
		while (matcher.find()) {
			urlList.add(matcher.group());
		}
		String gif = "http://([\\w-]+\\.)+[\\w-]+(/[\\w-\\./?%=]*)?\\.gif";
		Pattern patternGif = Pattern.compile(gif);
		Matcher matcherGif = patternGif.matcher(html);
		while (matcherGif.find()) {
			urlList.add(matcherGif.group());
		}
		return urlList;
	}

	public String filterText(String urlPath) {
		StringBean sb = new StringBean();
		sb.setLinks(false);
		sb.setURL(urlPath);
		return sb.getStrings();
	}

}
